package week

import (
	"menu-generation-go/utils"
	"time"

	"github.com/gin-gonic/gin"
	"menu-generation-go/database"
	"menu-generation-go/handlers/common"
	"menu-generation-go/models"
)

type WeekMenuHandler struct {
	DB *database.Database
}

func NewWeekMenuHandler(db *database.Database) *WeekMenuHandler {
	return &WeekMenuHandler{DB: db}
}

// CreateWeekMenu 创建周菜单
// @Summary 创建周菜单
// @Description 创建新的周菜单并生成每日模板
// @Tags 周菜单
// @Accept json
// @Produce json
// @Param input body CreateWeekMenuRequest true "周菜单信息"
// @Success 200 {object} common.Response{data=models.WeekMenu}
// @Router /api/week-menus [post]
func (h *WeekMenuHandler) CreateWeekMenu(c *gin.Context) {
	type CreateWeekMenuRequest struct {
		WeekNumber string `json:"weekNumber" binding:"required"`
		Year       int    `json:"year" binding:"required"`
		StartDate  string `json:"startDate" binding:"required"`
		EndDate    string `json:"endDate" binding:"required"`
	}

	var input CreateWeekMenuRequest
	if err := c.ShouldBindJSON(&input); err != nil {
		common.SendErrJSON("无效输入: "+err.Error(), c)
		return
	}
	sess, err := common.GetUserSession(c)
	if err != nil {
		common.SendErrJSON(err.Error(), c)
		return
	}
	// 验证日期格式和间隔
	startTime, err := time.Parse("2006-01-02", input.StartDate)
	if err != nil {
		common.SendErrJSON("开始日期格式无效，请使用YYYY-MM-DD格式", c)
		return
	}

	endTime, err := time.Parse("2006-01-02", input.EndDate)
	if err != nil {
		common.SendErrJSON("结束日期格式无效，请使用YYYY-MM-DD格式", c)
		return
	}

	// 检查开始日期是否在结束日期之后
	if startTime.After(endTime) {
		common.SendErrJSON("开始日期不能在结束日期之后", c)
		return
	}

	// 计算日期差
	days := int(endTime.Sub(startTime).Hours()/24) + 1
	if days > 7 {
		common.SendErrJSON("周菜单时间跨度不能超过7天", c)
		return
	}
	var weekMenu models.WeekMenus
	h.DB.DB.Where("week_number = ? AND start_date = ? AND end_date = ? and year = ?", input.WeekNumber, input.StartDate, input.EndDate, input.Year).First(&weekMenu)
	if weekMenu.ID != 0 {
		common.SendErrJSON("该周菜单已存在", c)
		return
	}
	weekMenu = models.WeekMenus{
		Year:       input.Year,
		WeekNumber: utils.StrToInt(input.WeekNumber),
		StartDate:  input.StartDate,
		EndDate:    input.EndDate,
		Status:     "draft",
		CreatedBy:  sess.UserID,
		CreatedAt:  time.Now(),
		UpdatedAt:  time.Now(),
	}

	result := h.DB.DB.Create(&weekMenu)
	if result.Error != nil {
		common.SendErrJSON("创建周菜单失败", c)
		return
	}

	// 生成每日菜单模板
	if err := h.generateDayMenus(weekMenu.ID, input.StartDate, input.EndDate); err != nil {
		common.SendErrJSON("生成每日菜单失败", c)
		return
	}

	common.Ok(c, weekMenu)
}

// ListWeekMenus 获取周菜单列表
// @Summary 获取周菜单列表
// @Description 获取所有周菜单记录
// @Tags 周菜单
// @Accept json
// @Produce json
// @Success 200 {object} common.Response{data=[]models.WeekMenu}
// @Router /api/week-menus [get]
func (h *WeekMenuHandler) ListWeekMenus(c *gin.Context) {
	type ListWeekMenusRequest struct {
		WeekNumber int    `json:"weekNumber"` // 按周数筛选（可选）
		Year       int    `json:"year"`       // 按周数筛选（可选）
		StartDate  string `json:"startDate"`  // 开始日期（可选）
		EndDate    string `json:"endDate"`    // 结束日期（可选）
		Page       int    `json:"page"`       // 页码（从1开始）
		PageSize   int    `json:"pageSize"`   // 每页数量
	}

	var input ListWeekMenusRequest
	if err := c.ShouldBindJSON(&input); err != nil {
		common.SendErrJSON("无效输入: "+err.Error(), c)
		return
	}

	// 设置分页默认值
	if input.Page <= 0 {
		input.Page = 1
	}
	if input.PageSize <= 0 {
		input.PageSize = 10 // 默认每页10条
	}

	// 获取当前用户会话
	sess, err := common.GetUserSession(c)
	if err != nil {
		common.SendErrJSON(err.Error(), c)
		return
	}

	// 构建查询条件
	query := h.DB.DB.Where("created_by = ?", sess.UserID)

	// 添加可选条件
	if input.WeekNumber > 0 {
		query = query.Where("week_number = ?", input.WeekNumber)
	}
	if input.Year > 0 {
		query = query.Where("year = ?", input.Year)
	}
	if input.StartDate != "" {
		query = query.Where("start_date >= ?", input.StartDate)
	}
	if input.EndDate != "" {
		query = query.Where("end_date <= ?", input.EndDate)
	}

	// 计算分页偏移量
	offset := (input.Page - 1) * input.PageSize

	// 查询数据
	var weekMenus []models.WeekMenus
	result := query.Order("id DESC").
		Offset(offset).
		Limit(input.PageSize).
		Find(&weekMenus)

	if result.Error != nil {
		common.SendErrJSON("查询失败: "+result.Error.Error(), c)
		return
	}

	for i, _ := range weekMenus {
		weekMenus[i].Nickname = sess.NickName
	}
	// 返回分页结果（可扩展为包含总数等信息）
	common.Ok(c, gin.H{
		"list":  weekMenus,
		"total": input.Page,
	})
}

// DeleteWeekMenu 删除周菜单
// @Summary 删除周菜单
// @Description 删除周菜单及其关联数据
// @Tags 周菜单
// @Accept json
// @Produce json
// @Param id path int true "周菜单ID"
// @Success 200 {object} common.Response
// @Router /api/week-menus/{id} [delete]
func (h *WeekMenuHandler) DeleteWeekMenu(c *gin.Context) {
	type DeleteWeekMenuRequest struct {
		ID int `json:"id" binding:"required"`
	}

	var input DeleteWeekMenuRequest
	if err := c.ShouldBindJSON(&input); err != nil {
		common.SendErrJSON("无效输入: "+err.Error(), c)
		return
	}
	tx := h.DB.DB.Begin()

	// 1. 删除关联的菜品
	if err := tx.Exec("DELETE FROM menu_dishes WHERE day_menu_id IN (SELECT id FROM day_menus WHERE week_menu_id = ?)", input.ID).Error; err != nil {
		tx.Rollback()
		common.SendErrJSON("删除关联菜品失败", c)
		return
	}

	// 2. 删除每日菜单
	if err := tx.Where("week_menu_id = ?", input.ID).Delete(&models.DayMenus{}).Error; err != nil {
		tx.Rollback()
		common.SendErrJSON("删除每日菜单失败", c)
		return
	}

	// 3. 删除周菜单
	if err := tx.Delete(&models.WeekMenus{}, input.ID).Error; err != nil {
		tx.Rollback()
		common.SendErrJSON("删除周菜单失败", c)
		return
	}

	tx.Commit()
	common.Ok(c, gin.H{"message": "删除成功"})
}

// 生成每日菜单模板
func (h *WeekMenuHandler) generateDayMenus(weekMenuID uint, startDate, endDate string) error {
	start, err := time.Parse("2006-01-02", startDate)
	if err != nil {
		return err
	}

	end, err := time.Parse("2006-01-02", endDate)
	if err != nil {
		return err
	}

	for d := start; !d.After(end); d = d.AddDate(0, 0, 1) {
		dateStr := d.Format("2006-01-02")
		theWeek := d.Weekday().String()
		// 创建午餐菜单
		lunch := models.DayMenus{
			WeekMenuID: weekMenuID,
			Date:       dateStr,
			MealType:   "lunch",
			Status:     "pending",
			TheWeek:    theWeek,
			CreatedAt:  time.Now(),
			UpdatedAt:  time.Now(),
		}
		if err := h.DB.DB.Create(&lunch).Error; err != nil {
			return err
		}

		// 创建晚餐菜单
		dinner := models.DayMenus{
			WeekMenuID: weekMenuID,
			Date:       dateStr,
			MealType:   "dinner",
			Status:     "pending",
			TheWeek:    theWeek,
			CreatedAt:  time.Now(),
			UpdatedAt:  time.Now(),
		}
		if err := h.DB.DB.Create(&dinner).Error; err != nil {
			return err
		}
	}

	return nil
}
